#include "filter_packet_.h"
#include "protocal_header.h"
#include "pcap.h"
#include <time.h>
#include <stdio.h>
map<string, vector<string>>	downstream_traffic;
map<string, vector<string>> upstream_traffic;

extern map<string, vector<ASession> > userLog;
extern vector<string> files;

string getJaccount(const string &ip_addr_src, const string &ip_addr_dst, const string &log_time, int &type)  {
	if(userLog.count(ip_addr_src) != 0)  {
		type = 1;
		for(vector<ASession>::iterator it_vec = userLog[ip_addr_src].begin(); 
			it_vec != userLog[ip_addr_src].end(); it_vec ++)  {
				if(log_time <= it_vec->end_time_ && log_time >= it_vec->start_time_)  {
					return it_vec->jaccount_;
				}
		}
			
	}
	if(userLog.count(ip_addr_dst) != 0)  {
		type = 0;
		for(vector<ASession>::iterator it_vec = userLog[ip_addr_dst].begin(); 
			it_vec != userLog[ip_addr_dst].end(); it_vec ++)  {
				if(log_time <= it_vec->end_time_ && log_time >= it_vec->start_time_)  {
					return it_vec->jaccount_;
				}
		}
			
	}
	cout << "Error! Do not find this ip address in user log!" << endl;
	return "";	
}

#define IPV4 0X0800
#define IP_HL(ip)		(((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)		(((ip)->ip_vhl) >> 4)
#define TH_OFF(th)	(((th)->th_offx2 & 0xf0) >> 4)

void dispatchPacket(const string &filename)  {
	char errbuff[PCAP_ERRBUF_SIZE];
	pcap_t *pcap = pcap_open_offline(filename.c_str(), errbuff);

	struct pcap_pkthdr* header;
	const u_char* data;

	u_int packetCount = 0;
	while(int returnValue = pcap_next_ex(pcap, &header, &data) >= 0) {
		printf("Packet # %i\n", ++packetCount);
		printf("Packet size: %d bytes\n", header->len);

		if (header->len != header->caplen) {
            printf("Warning! Capture size different than packet size: %ld bytes\n", header->len);
			continue;
		 }
		 printf("Epoch Time: %d:%d seconds\n", header->ts.tv_sec, header->ts.tv_usec);

		 Ethernet_hdr* eth_hdr = (struct Ethernet_hdr*) (data);

		 if(eth_hdr->ether_type != IPV4 ) 
			 continue;

		 IP_hdr* ip_hdr = (struct IP_hdr*) (data+SIZE_ETHERNET);
		 u_int size_ip = IP_HL(ip_hdr) * 4;
		 if(size_ip < 20) {
			printf("Invalid IP Header\n");
			continue;
		 }
		
		 struct in_addr ip_src = ip_hdr->ip_src;
		 struct in_addr ip_dst = ip_hdr->ip_dst;

		 string strIP_src = inet_ntoa(ip_src);
		 string str_IP_dst = inet_ntoa(ip_dst);
		 
		 char buf[30];
		 time_t ltime = header->ts.tv_sec;
		 struct tm *timeptr = localtime(&ltime);
		 strftime(buf,30,"%H:%M:%S\n" , timeptr);
		 string str_second = buf;

		 int type = -1;
		 string jac_name = getJaccount(strIP_src, str_IP_dst, str_second, type);

		 if(jac_name.size() <= 0)
			 continue;

		 // downstream
		 if(type == 0)  {
			 if(downstream_traffic.count(str_IP_dst) == 0)  {
				vector<string> tmp;
				downstream_traffic[str_IP_dst] = tmp;
			 }
			 string str = (char*)(data);
			 downstream_traffic[str_IP_dst].push_back(str);
			 continue;
		 }
		 // upstream
		 if(type == 1)  {
			if(downstream_traffic.count(str_IP_dst) == 0)  {
				vector<string> tmp;
				downstream_traffic[str_IP_dst] = tmp;
			 }
		 }
	}
}

void choosePcapFiles(const string &dirname)  {
	
}